/////////////////////////////////////////////////////////////////////////////
// Name:        toolbarcustdlg.cpp
// Purpose:
// Author:      Julian Smart
// Modified by:
// Created:     11/29/2006 10:15:46 AM
// RCS-ID:
// Copyright:   (c) Anthemion Software Ltd.
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"

#include "wx/fs_mem.h"

////@begin includes
////@end includes

#include "toolbarcust/toolbarcustdlg.h"

#ifdef __WXMAC__
#include "toolbarcust/bitmaps/checked_mac.xpm"
#include "toolbarcust/bitmaps/unchecked_mac.xpm"
#else
#include "toolbarcust/bitmaps/checked.xpm"
#include "toolbarcust/bitmaps/unchecked.xpm"
#endif

#ifdef __WXMSW__
#include <windows.h>
#include "wx/msw/winundef.h"
#include "wx/msw/uxtheme.h"
#endif

// Get a reasonable themed border style
static wxBorder GetSuitableThemedBorderStyle()
{
#if defined(__WXMSW__)
#if wxUSE_UXTHEME
    // If on Windows XP/Vista, use more appropriate colours.
    if (wxUxThemeEngine::GetIfActive())
    {
#if wxCHECK_VERSION(2,8,4)
        return wxBORDER_THEME;
#else
        return wxBORDER_SIMPLE;
#endif
    }
#endif
    return wxBORDER_SUNKEN;
#else
    return wxBORDER_SUNKEN;
#endif
}

////@begin XPM images
////@end XPM images

/*!
 * wxToolBarCustomisationDialog type definition
 */

IMPLEMENT_DYNAMIC_CLASS( wxToolBarCustomisationDialog, wxDialog )

/*!
 * wxToolBarCustomisationDialog event table definition
 */

BEGIN_EVENT_TABLE( wxToolBarCustomisationDialog, wxDialog )
    EVT_CHECKLISTBOX(wxID_ANY, wxToolBarCustomisationDialog::OnCheckListBoxToggled)

////@begin wxToolBarCustomisationDialog event table entries
    EVT_CHOICE( ID_TOOLBAR_CUST_TOOLBARS, wxToolBarCustomisationDialog::OnToolbarCustToolbarsSelected )

    EVT_CHECKBOX( ID_ShowToolBarCtrl, wxToolBarCustomisationDialog::OnShowToolBarCtrlClick )

    EVT_CHECKBOX( ID_ShowLabelsCtrl, wxToolBarCustomisationDialog::OnShowLabelsCtrlClick )
    EVT_UPDATE_UI( ID_ShowLabelsCtrl, wxToolBarCustomisationDialog::OnShowLabelsCtrlUpdate )

////@end wxToolBarCustomisationDialog event table entries

END_EVENT_TABLE()

/*!
 * wxToolBarCustomisationDialog constructors
 */

wxToolBarCustomisationDialog::wxToolBarCustomisationDialog( )
{
    Init();
}

wxToolBarCustomisationDialog::wxToolBarCustomisationDialog( wxToolBarCustomisationManager* manager, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
    Init();
    Create(manager, parent, id, caption, pos, size, style);
}

/*!
 * wxToolBarCustomisationDialog creator
 */

bool wxToolBarCustomisationDialog::Create( wxToolBarCustomisationManager* manager, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
    m_manager = manager;

////@begin wxToolBarCustomisationDialog creation
    SetExtraStyle(wxWS_EX_BLOCK_EVENTS|wxDIALOG_EX_CONTEXTHELP);
    wxDialog::Create( parent, id, caption, pos, size, style );

    CreateControls();
    if (GetSizer())
    {
        GetSizer()->SetSizeHints(this);
    }
    Centre();
////@end wxToolBarCustomisationDialog creation
    return true;
}

/*!
 * Member initialisation
 */

void wxToolBarCustomisationDialog::Init()
{
    m_manager = NULL;
    m_showToolTips = false;
////@begin wxToolBarCustomisationDialog member initialisation
    m_toolbarsCtrl = NULL;
    m_showToolBarCtrl = NULL;
    m_showLabelsCtrl = NULL;
    m_toolListCtrl = NULL;
////@end wxToolBarCustomisationDialog member initialisation
}
/*!
 * Control creation for wxToolBarCustomisationDialog
 */

void wxToolBarCustomisationDialog::CreateControls()
{
////@begin wxToolBarCustomisationDialog content construction
    wxToolBarCustomisationDialog* itemDialog1 = this;

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    itemDialog1->SetSizer(itemBoxSizer2);

    wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5);

    wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5);

    wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer4->Add(itemBoxSizer5, 0, wxALIGN_CENTER_VERTICAL, 5);

    wxStaticText* itemStaticText6 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Toolbar:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxArrayString m_toolbarsCtrlStrings;
    m_toolbarsCtrl = new wxChoice( itemDialog1, ID_TOOLBAR_CUST_TOOLBARS, wxDefaultPosition, wxSize(300, -1), m_toolbarsCtrlStrings, 0 );
    itemBoxSizer5->Add(m_toolbarsCtrl, 1, wxGROW|wxALL, 5);

    itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

    wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer9, 0, wxGROW, 5);

    m_showToolBarCtrl = new wxCheckBox( itemDialog1, ID_ShowToolBarCtrl, _("&Show this toolbar"), wxDefaultPosition, wxDefaultSize, 0 );
    m_showToolBarCtrl->SetValue(false);
    itemBoxSizer9->Add(m_showToolBarCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_showLabelsCtrl = new wxCheckBox( itemDialog1, ID_ShowLabelsCtrl, _("Show &labels"), wxDefaultPosition, wxDefaultSize, 0 );
    m_showLabelsCtrl->SetValue(false);
    itemBoxSizer9->Add(m_showLabelsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

    wxStaticText* itemStaticText13 = new wxStaticText( itemDialog1, wxID_STATIC, _("T&ools:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer3->Add(itemStaticText13, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    m_toolListCtrl = new wxToolCheckListBox( itemDialog1, ID_TOOLBAR_CUST_TOOLS, wxDefaultPosition, wxSize(100, 220), 0 );
    itemBoxSizer3->Add(m_toolListCtrl, 1, wxGROW|wxALL, 5);

    wxBoxSizer* itemBoxSizer15 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer15, 0, wxGROW, 5);

    itemBoxSizer15->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxButton* itemButton17 = new wxButton( itemDialog1, wxID_OK, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer15->Add(itemButton17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

////@end wxToolBarCustomisationDialog content construction

    int i;
    for (i = 0; i < m_manager->GetCount(); i++)
    {
        wxToolBarCustomisationInfo* info = m_manager->GetNth(i);
        m_toolbarsCtrl->Append(wxGetTranslation(info->GetName()));
    }
    if (m_toolbarsCtrl->GetCount() > 0)
    {
        int n = 0;
        if (!m_initialToolBar.IsEmpty())
        {
            int index = m_manager->FindIndex(m_initialToolBar);
            if (index != -1)
                n = index;
        }

        m_toolbarsCtrl->SetSelection(n);
        ShowToolbar(n /* m_manager->GetNth(n)->GetName() */);
    }
}

/// Show toolbar
void wxToolBarCustomisationDialog::ShowToolbar(int n/* const wxString& name */)
{
    wxToolBarCustomisationInfo* info = m_manager->GetNth(n);
    if (info)
    {
        m_toolListCtrl->UseCustomisation(info);

        m_showToolBarCtrl->SetValue(info->IsToolBarEnabled());

        if (info->GetCanHaveLabels())
            m_showLabelsCtrl->SetValue(info->GetUseLabels());
        else
            m_showLabelsCtrl->SetValue(false);
    }
}

// Did this toolbar change?
bool wxToolBarCustomisationDialog::ToolBarChanged(const wxString& name) const
{
    return ToolBarChanged(m_manager->FindIndex(name));
}

// Did this toolbar visibility change?
bool wxToolBarCustomisationDialog::ToolBarVisibilityChanged(const wxString& name) const
{
    return ToolBarVisibilityChanged(m_manager->FindIndex(name));
}

// Did this toolbar text labels status change?
bool wxToolBarCustomisationDialog::ToolBarLabelsChanged(const wxString& name) const
{
    return ToolBarLabelsChanged(m_manager->FindIndex(name));
}

// Did this toolbar's tools change?
bool wxToolBarCustomisationDialog::ToolsChanged(const wxString name) const
{
    return ToolsChanged(m_manager->FindIndex(name));
}

// Get the list of toolbar customisations that were changed
wxArrayString wxToolBarCustomisationDialog::GetChanged() const
{
    wxArrayString names;
    size_t i;
    for (i = 0; i < m_changed.GetCount(); i++)
    {
        wxToolBarCustomisationInfo* item = m_manager->GetNth(m_changed[i]);
        if (item)
            names.Add(item->GetName());
    }
    return names;
}

/*!
 * Should we show tooltips?
 */

bool wxToolBarCustomisationDialog::ShowToolTips()
{
    return m_showToolTips;
}

/*!
 * Get bitmap resources
 */

wxBitmap wxToolBarCustomisationDialog::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin wxToolBarCustomisationDialog bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end wxToolBarCustomisationDialog bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon wxToolBarCustomisationDialog::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin wxToolBarCustomisationDialog icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end wxToolBarCustomisationDialog icon retrieval
}

/*!
 * wxEVT_COMMAND_CHOICE_SELECTED event handler for ID_TOOLBAR_CUST_TOOLBARS
 */

void wxToolBarCustomisationDialog::OnToolbarCustToolbarsSelected( wxCommandEvent& WXUNUSED(event) )
{
    ShowToolbar(m_toolbarsCtrl->GetSelection());
}

/*!
 * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_TOOLBAR_CUST_SHOW_TOOLBAR
 */

void wxToolBarCustomisationDialog::OnShowToolBarCtrlClick( wxCommandEvent& WXUNUSED(event) )
{
    int n = m_toolbarsCtrl->GetSelection();
    if (n != -1)
    {
        wxToolBarCustomisationInfo* info = m_manager->GetNth(n);
        if (info)
        {
            info->SetToolBarEnabled(m_showToolBarCtrl->IsChecked());
            if (m_changed.Index(n) == wxNOT_FOUND)
                m_changed.Add(n);
            if (m_visibilityChanged.Index(n) == wxNOT_FOUND)
                m_visibilityChanged.Add(n);
        }
    }
}

/// An option was toggled
void wxToolBarCustomisationDialog::OnCheckListBoxToggled(wxCommandEvent& WXUNUSED(event))
{
    int n = m_toolbarsCtrl->GetSelection();
    if (n != wxNOT_FOUND)
    {
        if (m_changed.Index(n) == wxNOT_FOUND)
            m_changed.Add(n);
        if (m_toolsChanged.Index(n) == wxNOT_FOUND)
            m_toolsChanged.Add(n);
    }
}

/*!
 * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_ShowLabelsCtrl
 */

void wxToolBarCustomisationDialog::OnShowLabelsCtrlClick( wxCommandEvent& WXUNUSED(event) )
{
    int n = m_toolbarsCtrl->GetSelection();
    if (n != wxNOT_FOUND)
    {
        wxToolBarCustomisationInfo* info = m_manager->GetNth(n);
        if (info && info->GetCanHaveLabels())
        {
            info->SetUseLabels(m_showLabelsCtrl->IsChecked());
            if (m_changed.Index(n) == wxNOT_FOUND)
                m_changed.Add(n);
            if (m_labelsChanged.Index(n) == wxNOT_FOUND)
                m_labelsChanged.Add(n);
        }
    }
}


/*!
 * wxEVT_UPDATE_UI event handler for ID_ShowLabelsCtrl
 */

void wxToolBarCustomisationDialog::OnShowLabelsCtrlUpdate( wxUpdateUIEvent& event )
{
    int n = m_toolbarsCtrl->GetSelection();
    if (n != wxNOT_FOUND)
    {
        wxToolBarCustomisationInfo* info = m_manager->GetNth(n);
        event.Enable(info != NULL && info->GetCanHaveLabels());
    }
    else
        event.Enable(false);
}


/*!
 * wxToolCheckListBox class
 */

IMPLEMENT_CLASS(wxToolCheckListBox, wxHtmlListBox)

BEGIN_EVENT_TABLE(wxToolCheckListBox, wxHtmlListBox)
    EVT_LEFT_DOWN(wxToolCheckListBox::OnLeftDown)
END_EVENT_TABLE()

wxToolCheckListBox::wxToolCheckListBox(wxWindow* parent, wxWindowID id, const wxPoint& pos,
        const wxSize& size, long style)
{
    wxBorder borderStyle = (wxBorder) (style & wxBORDER_MASK);
    if (borderStyle == wxBORDER_DEFAULT)
        style |= GetSuitableThemedBorderStyle();

    wxHtmlListBox::Create(parent, id, pos, size, style);

    m_info = NULL;

#ifdef __WXMAC__
    wxBitmap bitmap1(checked_mac_xpm);
    wxBitmap bitmap2(unchecked_mac_xpm);
#else
    wxBitmap bitmap1(checked_xpm);
    wxBitmap bitmap2(unchecked_xpm);
#endif

    wxMemoryFSHandler::AddFile(wxT("checked.png"), bitmap1, wxBITMAP_TYPE_PNG);
    wxMemoryFSHandler::AddFile(wxT("unchecked.png"), bitmap2, wxBITMAP_TYPE_PNG);

    SetSelectionBackground(*wxWHITE);
}

wxToolCheckListBox::~wxToolCheckListBox()
{
    wxMemoryFSHandler::RemoveFile(wxT("checked.png"));
    wxMemoryFSHandler::RemoveFile(wxT("unchecked.png"));

    ClearMemoryBitmaps();
}

wxColour wxToolCheckListBox::GetSelectedTextColour(const wxColour& WXUNUSED(colFg)) const
{
    return *wxBLACK;
}

wxColour wxToolCheckListBox::GetSelectedTextBgColour(const wxColour& WXUNUSED(colBg)) const
{
    return *wxWHITE;
}

/// Returns the HTML for this item
wxString wxToolCheckListBox::OnGetItem(size_t n) const
{
    wxString str;

    if (m_info)
    {
        const wxToolBarCustomisationInfoItem& item = m_info->GetItem(n);
        if (item.IsSeparator())
        {
            str = wxT("<hr>");
        }
        else
        {
            wxString name = item.GetName();
            wxString translatedName = wxGetTranslation(name);
            wxString checkImage;
            if (item.IsEnabled())
                checkImage = wxT("<img src=\"memory:checked.png\">");
            else
                checkImage = wxT("<img src=\"memory:unchecked.png\">");
            wxString toolImage;
            if (item.GetNormalBitmap().Ok())
            {
                toolImage = wxString::Format(wxT("<img src=\"memory:%s\">"), item.GetName().c_str());
            }
            else
            {
            }

            str = wxString::Format(wxT("<table border=0><tr><td valign=center width=16 height=32>%s</td><td valign=center width=%d height=%d>%s</td><td valign=center>%s</td></tr></table>"),
                checkImage.c_str(), m_maxBitmapSize.x, m_maxBitmapSize.y, toolImage.c_str(), translatedName.c_str());
        }
    }
    else
    {
        str = wxString::Format(wxT("<b>Item %d</b>"), (int) n);
    }

    return str;
}

/// Updates the list, for example if the icon list changed
void wxToolCheckListBox::UpdateList()
{
    if (m_info)
    {
        SetItemCount(m_info->GetTotalItemCount());
        RefreshAll();
    }
    else
    {
        SetItemCount(0);
        RefreshAll();
    }
}

#if 0
/// Select one item
void wxToolCheckListBox::Select(const wxString& name, bool select, bool refresh)
{
    if (select)
    {
        if (m_selections.Index(name) == wxNOT_FOUND && m_iconList && m_iconList->FindIcon(name))
            m_selections.Add(name);
    }
    else
    {
        if (m_selections.Index(name) != wxNOT_FOUND)
            m_selections.Remove(name);
    }
    if (refresh)
        RefreshAll();
}

/// Is this item selected?
bool wxToolCheckListBox::IsSelected(const wxString& name) const
{
    return (m_selections.Index(name) != wxNOT_FOUND);
}
#endif

void wxToolCheckListBox::OnLeftDown(wxMouseEvent& event)
{
    int i = HitTest(event.GetPosition());

    if ( i != wxNOT_FOUND && (event.GetPosition().x < 25))
    {
        if (m_info)
        {
            wxToolBarCustomisationInfoItem& item = m_info->GetItem(i);
            if (!item.IsSeparator())
            {
                item.Enable(!item.IsEnabled());
                RefreshAll();

                wxCommandEvent cmdEvent(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, GetId());
                GetEventHandler()->ProcessEvent(cmdEvent);
            }
        }
    }

    event.Skip();
}

/// Use the customisation
void wxToolCheckListBox::UseCustomisation(wxToolBarCustomisationInfo* info)
{
    ClearMemoryBitmaps();
    SetCustomisation(info);
    if (info)
    {
        AddMemoryBitmaps();
    }
    UpdateList();
}

/// Clear the memory bitmaps
void wxToolCheckListBox::ClearMemoryBitmaps()
{
    size_t i;
    for (i = 0; i < m_memoryBitmaps.GetCount(); i++)
    {
        wxMemoryFSHandler::RemoveFile(m_memoryBitmaps[i]);
    }
    m_memoryBitmaps.Clear();
}

/// Add the memory bitmaps for the current info
void wxToolCheckListBox::AddMemoryBitmaps()
{
    if (m_info)
    {
        m_maxBitmapSize = wxSize(32,32);

        int i;
        for (i = 0; i < m_info->GetTotalItemCount(); i++)
        {
            const wxToolBarCustomisationInfoItem& item = m_info->GetItem(i);
            if (item.GetNormalBitmap().Ok())
            {
                wxMemoryFSHandler::AddFile(item.GetName(), item.GetNormalBitmap(), wxBITMAP_TYPE_PNG);
                m_memoryBitmaps.Add(item.GetName());

                if (item.GetNormalBitmap().GetWidth() > m_maxBitmapSize.x)
                    m_maxBitmapSize.x = item.GetNormalBitmap().GetWidth();
                if (item.GetNormalBitmap().GetHeight() > m_maxBitmapSize.y)
                    m_maxBitmapSize.y = item.GetNormalBitmap().GetHeight();
            }
        }
    }
}

